/*
XPTracker - Alternative Agile Tracking Tool
Copyright (C) 2006-2009  Stephen Starkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package org.xptracker.inject;

import com.google.inject.Provider;
import com.google.inject.name.Names;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.security.controller.StripesSecurityManager;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.quartz.spi.JobFactory;
import org.xptracker.domain.CurrentUserProvider;
import org.xptracker.persistence.AggregatePersistenceListeners;
import org.xptracker.search.*;
import org.xptracker.services.InjectingJobFactory;
import org.xptracker.services.ThreadLocalCurrentUserProvider;
import org.xptracker.services.XpSecurityManager;
import org.xptracker.util.UserConfigString;

import java.io.IOException;

public class AppModule extends BasicAppModule {
  protected void doBinding(UserConfigString dbDir, final UserConfigString searchDir) {
    bind(IndexingHelper.class).to(AnnotationDrivenIndexingHelper.class);
    bind(Searcher.class).to(LuceneSearcher.class);
    bind(StoryIndexer.class).to(LuceneIndexer.class);

    final Provider<Directory> directoryProvider = new Provider<Directory>() {
      public Directory get() {
        try {
          return FSDirectory.getDirectory(searchDir.get(), false);
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    };
    bind(Directory.class).toProvider(directoryProvider);

    final Analyzer analyzer = new StandardAnalyzer();
    bind(Analyzer.class).toInstance(analyzer);

    bind(IndexWriter.class).toProvider(new LuceneProvider<IndexWriter>() {
      public IndexWriter getLuceneItem() throws IOException {
        return new IndexWriter(directoryProvider.get(), analyzer, false);
      }
    });

    bind(IndexReader.class).toProvider(new LuceneProvider<IndexReader>() {
      protected IndexReader getLuceneItem() throws IOException {
        return IndexReader.open(directoryProvider.get());
      }
    });

    bind(IndexSearcher.class).toProvider(new LuceneProvider<IndexSearcher>() {
      protected IndexSearcher getLuceneItem() throws IOException {
        return new IndexSearcher(directoryProvider.get());
      }
    });

    bind(AggregatePersistenceListeners.class).to(AppPersistenceListeners.class);

    bind(JobFactory.class).to(InjectingJobFactory.class);
    bind(StripesSecurityManager.class).to(XpSecurityManager.class);
    bind(Resolution.class).annotatedWith(Names.named("unauthorizedResolution")).toProvider(new Provider<Resolution>() {
      public Resolution get() {
        return new ForwardResolution("/Main.action");
      }
    });

    bind(CurrentUserProvider.class).to(ThreadLocalCurrentUserProvider.class);
  }
}
